package com.originskyseed.platform.count.service.impl;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.stereotype.Component;

import com.originskyseed.platform.count.mapper.ContentCountAnchorMapper;
import com.originskyseed.platform.count.service.IContentCountAnchorService;
import com.originskyseed.platform.user.mapper.DeptMapper;
import com.originskyseed.platform.user.mapper.UserInfoMapper;
import com.originskyseed.platform.user.model.Dept;
import com.originskyseed.platform.user.model.UserInfo;

/**
 * Service接口实现类
 *
 * @author wlj
 */
@DubboService
@Component("contentAnchorService")
public class ContentCountAnchorServiceImpl implements IContentCountAnchorService {

	@Resource
	private ContentCountAnchorMapper contentCountAnchorMapper;

	@Resource
	private DeptMapper deptMapper;

	@Resource
	private UserInfoMapper userInfoMapper;

	/**
	 * 统计主播数量
	 *
	 * @return
	 * @throws Exception
	 */
	@Override
	public int countAnchorAmount(List<String> userIdList) throws Exception {
		return this.contentCountAnchorMapper.countAnchorAmount(userIdList);
	}

	/**
	 * 统计体系下主播礼物营收
	 *
	 * @return
	 * @throws Exception
	 */
	@Override
	public BigDecimal countAnchorGiftEarnings(List<String> userIdList) throws Exception {
		return this.contentCountAnchorMapper.countAnchorGiftEarnings(userIdList);
	}

	/**
	 * 统计方法
	 *
	 * @param userInfo
	 * @return
	 * @throws Exception
	 */
	@Override
	public Map<String, Object> countContentAnchorAndPlayer(UserInfo userInfo) throws Exception {
		Map<String, Object> resultMap = new HashMap<>();
		List<String> deptIdList = new ArrayList<>();
		Dept dept = this.deptMapper.selectByPrimaryKey(userInfo.getDeptId());
		this.selectDeptSon(dept.getCode(), deptIdList);
		// 挑选出来是主播的用户
		List<String> userIdList = this.userInfoMapper.selectAnchorIdsByDeptIds(deptIdList);
		if (userIdList != null && userIdList.size() > 0) {
			// 主播数量
			int anchorAmount = this.countAnchorAmount(userIdList);
			// 礼物营收
			BigDecimal giftEarnings = this.countAnchorGiftEarnings(userIdList);
			// 新用户消费
			BigDecimal newUserConsume = this.selectNewPlayerRechargeAmount(userIdList);
			// 优质用户数
			int highQualityUserNum = this.selectHighQualityUserNum(userIdList);
			// 充值用户数
			int rechargeUserNum = this.selectRechargeUserNum(userIdList);

			resultMap.put("anchorAmount", anchorAmount);
			resultMap.put("giftEarnings", giftEarnings);
			resultMap.put("newUserConsume", newUserConsume);
			resultMap.put("highQualityUserNum", highQualityUserNum);
			resultMap.put("rechargeUserNum", rechargeUserNum);
		}
		return resultMap;
	}

	/**
	 * 新用户消费
	 *
	 * @return
	 * @throws Exception
	 */
	@Override
	public BigDecimal selectNewPlayerRechargeAmount(List<String> userIdList) throws Exception {
		return this.contentCountAnchorMapper.selectNewPlayerRechargeAmount(userIdList);
	}

	/**
	 * 优质用户数
	 * 
	 * @param userIdList
	 * @return
	 * @throws Exception
	 */
	@Override
	public int selectHighQualityUserNum(List<String> userIdList) throws Exception {
		return this.contentCountAnchorMapper.selectHighQualityUserNum(userIdList);
	}

	/**
	 * 充值用户数
	 * 
	 * @param userIdList
	 * @return
	 * @throws Exception
	 */
	@Override
	public int selectRechargeUserNum(List<String> userIdList) throws Exception {
		return this.contentCountAnchorMapper.selectRechargeUserNum(userIdList);
	}

	/**
	 * 利润趋势
	 * 
	 * @return
	 * @throws Exception
	 */
	@Override
	public List<Map<String, Object>> profitTrend(int type, UserInfo userInfo) throws Exception {
		List<Map<String, Object>> list = new ArrayList<>();
		// 查询所有体系
		Dept deptInfo = new Dept();
		deptInfo.setSourceSys(1);
		deptInfo.setType(8);
		List<Dept> deptList = this.deptMapper.selectList(deptInfo);
		if (deptList != null && deptList.size() > 0) {
			for (Dept dept : deptList) {
				// 查询部门子节点
				List<String> deptIdList = new ArrayList<>();
				selectDeptSon(dept.getCode(), deptIdList);
				// 查询主播
				List<String> userIdList = this.userInfoMapper.selectAnchorIdsByDeptIds(deptIdList);
				// 查询营收
				BigDecimal giftEarnings = this.contentCountAnchorMapper.countAnchorGiftEarnings(userIdList);
				// 查询成本 *注：总成本 = basePay + 开放平台体系财务账单设置的成本
				BigDecimal basePay = this.contentCountAnchorMapper.selectBasePay(userIdList);
			}
		}
		return list;
	}

	/**
	 * 查询所有的子集id
	 *
	 * @param parentCode
	 * @param list
	 * @throws Exception
	 */
	private void selectDeptSon(String parentCode, List<String> list) throws Exception {
		List<Dept> deptList = this.deptMapper.selectByParentCode(parentCode);

		if (deptList != null) {
			for (Dept dept1 : deptList) {
				list.add(dept1.getId());
				selectDeptSon(dept1.getCode(), list);
			}
		}
	}

	/**
	 * 利润趋势 查询成本和毛利和净利润
	 * 
	 * @return
	 * @throws Exception
	 */
	public Map<String, Object> selectBasePayAndGrossProfit(List<String> list, int type) throws Exception {
		Map<String, Object> resultMap = new HashMap<>();
		// 查询成本
		BigDecimal basePay = this.contentCountAnchorMapper.selectBasePay(list);

		// 根据日期平摊成本,和查询毛利
		String startTime = null;
		String endTime = null;
		DateUtils dateUtils = new DateUtils();
		// 日
		if (type == 0) {
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
			String date = sdf.format(new Date());
			startTime = date;
			endTime = date;

			// 当前月的天数
			int monthDay = dateUtils.getCurrentMonthDay();
			basePay = basePay.divide(new BigDecimal(monthDay),2, BigDecimal.ROUND_HALF_UP);
			// 周
		} else if (type == 1) {
			startTime = dateUtils.getCurrentWeekDayStartTime();
			endTime = dateUtils.getCurrentWeekDayEndTime();

			basePay = basePay.divide(new BigDecimal(4));
			// 月
		} else if (type == 2) {
			startTime = dateUtils.getCurrentMonthStartTime();
			endTime = dateUtils.getCurrentMonthEndTime();
			// 季
		} else if (type == 3) {
			startTime = dateUtils.getCurrentQuarterStartTime();
			endTime = dateUtils.getCurrentQuarterEndTime();

			basePay = basePay.multiply(new BigDecimal(4));
			// 年
		} else if (type == 4) {
			startTime = dateUtils.getCurrentYearStartTime();
			endTime = dateUtils.getCurrentYearEndTime();

			basePay = basePay.multiply(new BigDecimal(12));
		}

		// 封装参数
		Map<String, Object> map = new HashMap<>();
		map.put("list", list);
		map.put("startTime", startTime);
		map.put("endTime", endTime);

		// 毛利
		BigDecimal grossProfit = this.contentCountAnchorMapper.selectGrossProfit(map).multiply(new BigDecimal(0.2));
		resultMap.put("basePay", basePay);
		resultMap.put("grossProfit", grossProfit);
		resultMap.put("profit", grossProfit.subtract(basePay));
		return resultMap;
	}

	private class DateUtils {

		// 日期格式化
		private final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

		/**
		 * 获得本周的第一天，周一
		 *
		 * @return
		 */
		public String getToday() {
			Calendar c = Calendar.getInstance();
			return sdf.format(c.getTime());
		}

		/**
		 * 获得昨天的日期
		 *
		 * @return
		 */
		public String getYesterday() {
			Calendar c = Calendar.getInstance();
			try {
				c.add(Calendar.DATE, -1);
			} catch (Exception e) {
				e.printStackTrace();
			}
			return sdf.format(c.getTime());
		}

		/**
		 * 获得本周的第一天，周一
		 *
		 * @return
		 */
		public String getCurrentWeekDayStartTime() {
			Calendar c = Calendar.getInstance();
			try {
				int weekday = c.get(Calendar.DAY_OF_WEEK) - 2;
				c.add(Calendar.DATE, -weekday);
			} catch (Exception e) {
				e.printStackTrace();
			}
			return sdf.format(c.getTime());
		}

		/**
		 * 获得本周的最后一天，周日
		 *
		 * @return
		 */
		public String getCurrentWeekDayEndTime() {
			Calendar c = Calendar.getInstance();
			try {
				int weekday = c.get(Calendar.DAY_OF_WEEK);
				c.add(Calendar.DATE, 8 - weekday);
			} catch (Exception e) {
				e.printStackTrace();
			}
			return sdf.format(c.getTime());
		}

		/**
		 * 获得本月的开始时间
		 *
		 * @return
		 */
		public String getCurrentMonthStartTime() {
			Calendar c = Calendar.getInstance();
			try {
				c.set(Calendar.DATE, 1);
			} catch (Exception e) {
				e.printStackTrace();
			}
			return sdf.format(c.getTime());
		}

		/**
		 * 本月的结束时间
		 *
		 * @return
		 */
		public String getCurrentMonthEndTime() {
			Calendar c = Calendar.getInstance();
			try {
				c.set(Calendar.DATE, 1);
				c.add(Calendar.MONTH, 1);
				c.add(Calendar.DATE, -1);
			} catch (Exception e) {
				e.printStackTrace();
			}
			return sdf.format(c.getTime());
		}

		/**
		 * 当前年的开始时间
		 *
		 * @return
		 */
		public String getCurrentYearStartTime() {
			Calendar c = Calendar.getInstance();
			try {
				c.set(Calendar.MONTH, 0);
				c.set(Calendar.DATE, 1);
			} catch (Exception e) {
				e.printStackTrace();
			}
			return sdf.format(c.getTime());
		}

		/**
		 * 当前年的结束时间
		 *
		 * @return
		 */
		public String getCurrentYearEndTime() {
			Calendar c = Calendar.getInstance();
			try {
				c.set(Calendar.MONTH, 11);
				c.set(Calendar.DATE, 31);
			} catch (Exception e) {
				e.printStackTrace();
			}
			return sdf.format(c.getTime());
		}

		/**
		 * 当前季度的开始时间
		 *
		 * @return
		 */
		public String getCurrentQuarterStartTime() {
			Calendar c = Calendar.getInstance();
			int currentMonth = c.get(Calendar.MONTH) + 1;
			try {
				if (currentMonth >= 1 && currentMonth <= 3)
					c.set(Calendar.MONTH, 0);
				else if (currentMonth >= 4 && currentMonth <= 6)
					c.set(Calendar.MONTH, 3);
				else if (currentMonth >= 7 && currentMonth <= 9)
					c.set(Calendar.MONTH, 4);
				else if (currentMonth >= 10 && currentMonth <= 12)
					c.set(Calendar.MONTH, 9);
				c.set(Calendar.DATE, 1);
			} catch (Exception e) {
				e.printStackTrace();
			}
			return sdf.format(c.getTime());
		}

		/**
		 * 当前季度的结束时间
		 *
		 * @return
		 */
		public String getCurrentQuarterEndTime() {
			Calendar c = Calendar.getInstance();
			int currentMonth = c.get(Calendar.MONTH) + 1;
			try {
				if (currentMonth >= 1 && currentMonth <= 3) {
					c.set(Calendar.MONTH, 2);
					c.set(Calendar.DATE, 31);
				} else if (currentMonth >= 4 && currentMonth <= 6) {
					c.set(Calendar.MONTH, 5);
					c.set(Calendar.DATE, 30);
				} else if (currentMonth >= 7 && currentMonth <= 9) {
					c.set(Calendar.MONTH, 8);
					c.set(Calendar.DATE, 30);
				} else if (currentMonth >= 10 && currentMonth <= 12) {
					c.set(Calendar.MONTH, 11);
					c.set(Calendar.DATE, 31);
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
			return sdf.format(c.getTime());
		}

		/**
		 * 获取当月的 天数
		 */
		public int getCurrentMonthDay() {
			Calendar a = Calendar.getInstance();
			a.set(Calendar.DATE, 1);
			a.roll(Calendar.DATE, -1);
			int maxDate = a.get(Calendar.DATE);
			return maxDate;

		}

		/**
		 * 获取过去第几天的日期
		 *
		 * @param past
		 * @return
		 */
		public String getBeforeDate(int past) {
			Calendar calendar = Calendar.getInstance();
			calendar.set(Calendar.DAY_OF_YEAR, calendar.get(Calendar.DAY_OF_YEAR) - past);
			Date today = calendar.getTime();
			SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
			String result = format.format(today);
			return result;
		}

		/**
		 * 获取本周的所有日期
		 *
		 * @return
		 */
		public List<String> getWeakDayList() {
			Calendar cal = Calendar.getInstance();
			// 判断要计算的日期是否是周日，如果是则减一天计算周六的，否则会出问题，计算到下一周去了
			int dayWeek = cal.get(Calendar.DAY_OF_WEEK);// 获得当前日期是一个星期的第几天
			if (1 == dayWeek) {
				cal.add(Calendar.DAY_OF_MONTH, -1);
			}
			// System.out.println("要计算日期为:" + sdf.format(cal.getTime())); // 输出要计算日期
			// 设置一个星期的第一天，按中国的习惯一个星期的第一天是星期一
			cal.setFirstDayOfWeek(Calendar.MONDAY);
			// 获得当前日期是一个星期的第几天
			int day = cal.get(Calendar.DAY_OF_WEEK);
			// 根据日历的规则，给当前日期减去星期几与一个星期第一天的差值
			cal.add(Calendar.DATE, cal.getFirstDayOfWeek() - day);
			Date weekBegin = cal.getTime();
			// System.out.println("所在周星期一的日期：" + imptimeBegin);
			cal.add(Calendar.DATE, 6);
			Date weekEnd = cal.getTime();

			List<String> lDate = new ArrayList();
			lDate.add(sdf.format(weekBegin));
			Calendar calBegin = Calendar.getInstance();
			// 使用给定的 Date 设置此 Calendar 的时间
			calBegin.setTime(weekBegin);
			Calendar calEnd = Calendar.getInstance();
			// 使用给定的 Date 设置此 Calendar 的时间
			calEnd.setTime(weekEnd);
			// 测试此日期是否在指定日期之后
			while (weekEnd.after(calBegin.getTime())) {
				// 根据日历的规则，为给定的日历字段添加或减去指定的时间量
				calBegin.add(Calendar.DAY_OF_MONTH, 1);
				lDate.add(sdf.format(calBegin.getTime()));
			}
			return lDate;
		}

		/**
		 * 获取上周的所有日期
		 *
		 * @return
		 */
		public List<String> getLastWeakDayList() {
			Calendar calendar1 = Calendar.getInstance();
			Calendar calendar2 = Calendar.getInstance();
			int dayOfWeek = calendar1.get(Calendar.DAY_OF_WEEK) - 1;
			int offset1 = 1 - dayOfWeek;
			int offset2 = 7 - dayOfWeek;
			calendar1.add(Calendar.DATE, offset1 - 7);
			calendar2.add(Calendar.DATE, offset2 - 7);
			Date weekBegin = calendar1.getTime();
			Date weekEnd = calendar2.getTime();

			List<String> lDate = new ArrayList();
			lDate.add(sdf.format(weekBegin));
			Calendar calBegin = Calendar.getInstance();
			// 使用给定的 Date 设置此 Calendar 的时间
			calBegin.setTime(weekBegin);
			Calendar calEnd = Calendar.getInstance();
			// 使用给定的 Date 设置此 Calendar 的时间
			calEnd.setTime(weekEnd);
			// 测试此日期是否在指定日期之后
			while (weekEnd.after(calBegin.getTime())) {
				// 根据日历的规则，为给定的日历字段添加或减去指定的时间量
				calBegin.add(Calendar.DAY_OF_MONTH, 1);
				lDate.add(sdf.format(calBegin.getTime()));
			}
			return lDate;
		}

		/**
		 * 获取本月的所有日期
		 *
		 * @return
		 */
		public List<String> getMonthDayList() {
			Calendar calendar = Calendar.getInstance();
			int index = calendar.get(Calendar.DAY_OF_MONTH);
			calendar.add(Calendar.DATE, (1 - index));
			Date weekBegin = calendar.getTime();

			//
			calendar = Calendar.getInstance();
			calendar.add(Calendar.MONTH, 1);
			index = calendar.get(Calendar.DAY_OF_MONTH);
			calendar.add(Calendar.DATE, (-index));
			Date weekEnd = calendar.getTime();

			List<String> lDate = new ArrayList();
			lDate.add(sdf.format(weekBegin));
			Calendar calBegin = Calendar.getInstance();
			// 使用给定的 Date 设置此 Calendar 的时间
			calBegin.setTime(weekBegin);
			Calendar calEnd = Calendar.getInstance();
			// 使用给定的 Date 设置此 Calendar 的时间
			calEnd.setTime(weekEnd);
			// 测试此日期是否在指定日期之后
			while (weekEnd.after(calBegin.getTime())) {
				// 根据日历的规则，为给定的日历字段添加或减去指定的时间量
				calBegin.add(Calendar.DAY_OF_MONTH, 1);
				lDate.add(sdf.format(calBegin.getTime()));
			}
			return lDate;
		}

		/**
		 * 获取上月的所有日期
		 *
		 * @return
		 */
		public List<String> getLastMonthDayList() {
			Calendar calendar = Calendar.getInstance();
			calendar.add(Calendar.MONTH, -1);
			int index = calendar.get(Calendar.DAY_OF_MONTH);
			calendar.add(Calendar.DATE, (1 - index));
			Date weekBegin = calendar.getTime();

			//
			calendar = Calendar.getInstance();
			calendar.add(Calendar.MONTH, -1);
			calendar.add(Calendar.MONTH, 1);
			index = calendar.get(Calendar.DAY_OF_MONTH);
			calendar.add(Calendar.DATE, (-index));
			Date weekEnd = calendar.getTime();

			List<String> lDate = new ArrayList();
			lDate.add(sdf.format(weekBegin));
			Calendar calBegin = Calendar.getInstance();
			// 使用给定的 Date 设置此 Calendar 的时间
			calBegin.setTime(weekBegin);
			Calendar calEnd = Calendar.getInstance();
			// 使用给定的 Date 设置此 Calendar 的时间
			calEnd.setTime(weekEnd);
			// 测试此日期是否在指定日期之后
			while (weekEnd.after(calBegin.getTime())) {
				// 根据日历的规则，为给定的日历字段添加或减去指定的时间量
				calBegin.add(Calendar.DAY_OF_MONTH, 1);
				lDate.add(sdf.format(calBegin.getTime()));
			}
			return lDate;
		}

		String[] hoursList = { "01:00", "02:00", "03:00", "04:00", "05:00", "06:00", "07:00", "08:00", "09:00", "10:00", "11:00", "12:00", "13:00", "14:00", "15:00", "16:00", "17:00", "18:00", "19:00", "20:00", "21:00", "22:00", "23:00", "24:00" };

	}

	/**
	 * 获取日的数据
	 * 
	 * @param hoursList
	 * @param mapList
	 * @param dataList
	 */
	private void getDayData(String[] hoursList, List<Map<String, Object>> mapList, List<String> dataList) {
		for (String hours : hoursList) {
			boolean flag = true;
			for (Map<String, Object> map : mapList) {
				if (hours.equals(map.get("queryDate"))) {
					dataList.add((String) map.get("amount"));
					flag = false;
					break;
				}
			}
			if (flag) {
				dataList.add("0");
			}
		}
	}

	/**
	 * 获取日的数据
	 * 
	 * @param list
	 * @param mapList
	 * @param dataList
	 */
	private void getWeakMonthData(List<String> list, List<Map<String, Object>> mapList, List<String> dataList) {
		for (String hours : list) {
			boolean flag = true;
			for (Map<String, Object> map : mapList) {
				if (hours.equals(map.get("date"))) {
					dataList.add((String) map.get("amount"));
					flag = false;
					break;
				}
			}
			if (flag) {
				dataList.add("0");
			}
		}
	}

}
